home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2004 #9
/
Amiga Plus CD - 2004 - No. 09.iso
/
amigaplus
/
tools
/
dev_libs
/
feelin040718
/
demos
/
class3.c
< prev
next >
Wrap
C/C++ Source or Header
|
2004-08-03
|
8KB
|
285 lines
;/*
F_Create.rexx EXE Class3
QUIT
_________________________________________________________________________
Class3 Demo © 2000-2004 by Olivier LAVIALE <gofromiel@numericable.com>
*/
#include <intuition/intuition.h>
#include <libraries/feelin.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/feelin.h>
struct FeelinBase *FeelinBase;
// This is the instance data for our custom class.
struct LocalObjectData
{
FAreaData *AreaData;
WORD x,y, sx,sy;
};
///mNew
F_METHOD(ULONG,mNew)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
LOD -> AreaData = (FAreaData *) F_Get(Obj,FA_AreaData);
return F_SUPERDO();
}
//+
/// mSetup
/*
FC_Area creates a struct FeelinEventHandler on the fly depending the
events modified by the FM_ModifyHandler method. Using FM_ModifyHandler
it's a piece of cake ot request IDCMP events.
*/
F_METHOD(ULONG,mSetup)
{
F_Do(Obj,FM_ModifyHandler,IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS,0);
return F_SUPERDO();
}
//+
/// mCleanup
/*
FC_Area creates a struct FeelinEventHandler on the fly depending the
events modified by the FM_ModifyHandler method. Using FM_ModifyHandler
it's a piece of cake ot request IDCMP events.
*/
F_METHOD(ULONG,mCleanup)
{
F_Do(Obj,FM_ModifyHandler,0,IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS);
return F_SUPERDO();
}
//+
/// mAskMinMax
/*
FM_AskMinMax will be called before the window is opened. We need to tell
the FC_Window object the minimum and maximum size of our object.
When you are the first receiving the method the fields _minw() and
_minh() are set to zero and the fields _maxw() and _maxh() to FV_MAXMAX.
We can add values to _minw() and _minh() or set _maxw() and _maxh() if
we need to. Then we pass the method to our superclass.
When the method reaches FC_Area these values will be adjusted according
to FA_MinXxx, FA_FixedXxx and FA_FixXxx attributes.
*/
F_METHOD(ULONG,mAskMinMax)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
_minw += 100; _minh += 040;
_maxw = 500; _maxh = 300;
return F_SUPERDO();
}
//+
/// mDraw
/*
Draw method is called whenever Feelin feels (obviously ;-)) we should
render our object. This usually happens after layout is finished. Note:
You may only render within the rectangle _mx(), _my(), _mx2(), _my2().
*/
F_METHODM(void,mDraw,FS_Draw)
{
struct LocalObjectData *LOD = F_LOD(Class,Obj);
struct RastPort *rp = _rp;
/*
Let our superclass draw itself first, FC_Area would e.g. draw the frame
and clear the whole region. What it does exactly depends on flags.
*/
F_SUPERDO();
/*
IF FF_Draw_Object isn't set, we shouldn't draw anything. Feelin just
wanted to update the frame or something like that.
*/
if (Msg -> Flags & FF_Draw_Update) // called from our input method
{
if (LOD -> sx || LOD -> sy)
{
_BPen(_pens[FV_Pen_Shine]);
ScrollRaster(rp,LOD -> sx,LOD -> sy,_mx,_my,_mx2,_my2);
_BPen(_pens[FV_Pen_Dark]);
LOD -> sx = 0;
LOD -> sy = 0;
}
else
{
_APen(_pens[FV_Pen_Shadow]);
_Plot(LOD -> x,LOD -> y);
}
}
else if (Msg -> Flags & FF_Draw_Object)
{
_APen(_pens[FV_Pen_Shine]);
_Boxf(_mx,_my,_mx2,_my2);
}
}
//+
///mHandleEvent
/*
in mSetup() we said that we want get a message if mousebuttons or keys
pressed so we have to define the input-handler
Note :
This is really a good example, because it shows how to use critical
events carefully:
IDCMP_MOUSEMOVE is only needed when left-mousebutton is pressed, so we
dont request this until we get a SELECTDOWN-message and we reject
IDCMP_MOUSEMOVE immeditly after we get a SELECTUP-message
*/
F_METHODM(ULONG,mHandleEvent,FS_HandleEvent)
{
#define _between(a,x,b) ((x) >= (a) && (x) <= (b))
#define _isinobject(x,y) (_between(_mx,(x),_mx2) && _between(_my,(y),_my2))
/*
Note on Arrows handling :
If you don't handle arrows return NULL, this will allow Window object to
cycle through its chain using arrows instead of tabulations (more
confortable hu ?), else return FF_HandleEvent_Eat as usual.
*/
struct LocalObjectData *LOD = F_LOD(Class,Obj);
struct FeelinEvent *FEv = Msg -> FEv;
if (FEv -> Key)
{
switch (FEv -> Key)
{
case FV_KEY_LEFT: LOD -> sx = -1; break;
case FV_KEY_RIGHT: LOD -> sx = 1; break;
case FV_KEY_UP: LOD -> sy = -1; break;
case FV_KEY_DOWN: LOD -> sy = 1; break;
default: return NULL;
}
F_Draw(Obj,FF_Draw_Update);
return FF_HandleEvent_Eat; // Forbid arrow cycling, because *WE* handle key events.
}
else if (FEv -> Class == IDCMP_MOUSEBUTTONS)
{
if (FEv -> Code == SELECTDOWN)
{
if (_isinobject(FEv -> MouseX,FEv -> MouseY))
{
LOD -> x = FEv -> MouseX;
LOD -> y = FEv -> MouseY;
F_Draw(Obj,FF_Draw_Update);
// Only request IDCMP_MOUSEMOVE if we realy need it
F_Do(Obj,FM_ModifyHandler,IDCMP_MOUSEMOVE,0);
return FF_HandleEvent_Eat;
}
}
else
{
// Reject IDCMP_MOUSEMOVE because lmb is no longer pressed
F_Do(Obj,FM_ModifyHandler,0,IDCMP_MOUSEMOVE);
}
}
else if (FEv -> Class == IDCMP_MOUSEMOVE)
{
if (_isinobject(FEv -> MouseX,FEv -> MouseY))
{
LOD -> x = FEv -> MouseX;
LOD -> y = FEv -> MouseY;
F_Draw(Obj,FF_Draw_Update);
return FF_HandleEvent_Eat;
}
}
return NULL;
}
//+
/// Main
void main()
{
APTR app,win,myobj;
struct FeelinClass *cc;
static struct FeelinMethodEntry Handlers[] =
{
(FMethod) mNew, NULL, FM_New,
(FMethod) mSetup, NULL, FM_Setup,
(FMethod) mCleanup, NULL, FM_Cleanup,
(FMethod) mAskMinMax, NULL, FM_AskMinMax,
(FMethod) mDraw, NULL, FM_Draw,
(FMethod) mHandleEvent, NULL, FM_HandleEvent,
NULL
};
if (FeelinBase = (APTR) OpenLibrary("feelin.library",FV_VERSION))
{
/*
Create the new custom class with a call to F_CreateClassA().
This function returns a feelinClass structure. You must use Class -> Name
to create instance of your custom class. This Name is unique and made by
F_CreateClassA() when FA_Class_Name is NULL.
*/
if (cc = F_CreateClass(FA_Class_Super, FC_Area,
FA_Class_LODSize, sizeof (struct LocalObjectData),
FA_Class_MethodsTable, Handlers,
TAG_DONE))
{
app = AppObject,
Child, win = WindowObject,
FA_ID, MAKE_ID('M','A','I','N'),
FA_Window_Title, "A rather complex custom class",
FA_Window_Open, TRUE,
Child, VGroup,
Child, TextObject, FA_SetMax,FV_SetMaxH, DontChain, TextFrame, TextBack, FA_Text, "<align=center><i>Paint</i> with <b>mouse</b>,<br><i>Scroll</i> with <b>cursor keys</b>.", End,
Child, myobj = F_NewObj(cc -> Name, TextFrame, TAG_DONE),
End,
FA_Window_ActiveObject, myobj, // Safe here
End,
End;
if (app)
{
F_Do(win,FM_Notify,FA_Window_CloseRequest,TRUE, app,FM_Application_Shutdown,0);
F_Do(app,FM_Application_Run);
F_DisposeObj(app);
}
F_DeleteClass(cc);
}
else
{
Printf("Could not create custom class.\n");
}
CloseLibrary(FeelinBase);
}
else
{
Printf("Failed to open feelin.library\n");
}
}
//+